package com.lijinjiang.model;

import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;

/**
 * @Description 日期模型
 * @Author lijinjiang
 * @Date 2024-12-30 10:52
 */
public abstract class AbstractDateModel<T> implements DateModel<T> {
    private Integer hundredYear;//百年，比如2024年的百年为前两位：20
    private Integer tenYear;//十年，比如2024年的十年前缀为前三位：202
    private boolean selected;
    private LocalDateTime dateTime;
    private final Set<ChangeListener> changeListeners;

    protected AbstractDateModel() {
        changeListeners = new HashSet<>();
        selected = false;
        dateTime = LocalDateTime.now();//获取当前时间
        setHundredYear(dateTime.getYear() / 100);
        setTenYear(dateTime.getYear() / 10);
    }

    protected synchronized void fireChangeEvent() {
        for (ChangeListener changeListener : changeListeners) {
            changeListener.stateChanged(new ChangeEvent(this));
        }
    }


    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
        fireChangeEvent();
    }

    public T getValue() {
        if (!selected) {
            return null;
        }
        return fromLocalDateTime(dateTime);
    }

    public void setValue(LocalDateTime value) {
        if (value != null) {
            this.dateTime = value;
            setHundredYear(dateTime.getYear() / 100);
            setTenYear(dateTime.getYear() / 10);
            selected = true;
        } else {
            selected = false;
        }
        fireChangeEvent();
    }

    public void setDate(int year, int month, int day) {
        setHundredYear(year / 100);
        setTenYear(year / 10);
        setYear(year);
        setMonth(month);
        setDay(day);
    }

    public int getHundredYear() {
        return hundredYear;
    }

    public void setHundredYear(int hundredYear) {
        this.hundredYear = hundredYear;
    }

    public void addHundredYear(int hundredYear) {
        this.hundredYear = this.hundredYear + hundredYear;
    }

    public int getTenYear() {
        return tenYear;
    }

    public void setTenYear(int tenYear) {
        this.tenYear = tenYear;
        setHundredYear(tenYear / 10);
    }

    public void addTenYear(int tenYear) {
        this.tenYear = this.tenYear + tenYear;
        setHundredYear(this.tenYear / 10);
    }

    public int getYear() {
        return dateTime.getYear();
    }

    public void setYear(int year) {
        dateTime = dateTime.withYear(year);
        setHundredYear(year / 100);
        setTenYear(year / 10);
    }

    public void addYear(int years) {
        dateTime = dateTime.plusYears(years);
        setHundredYear(dateTime.getYear() / 100);
        setTenYear(dateTime.getYear() / 10);
    }

    public int getMonth() {
        return dateTime.getMonthValue();
    }

    public void setMonth(int month) {
        dateTime = dateTime.withMonth(month);
    }

    public void addMonth(int months) {
        dateTime = dateTime.plusMonths(months);
        setHundredYear(dateTime.getYear() / 100);
        setTenYear(dateTime.getYear() / 10);
    }

    public int getDay() {
        return dateTime.getDayOfMonth();
    }


    public void setDay(int day) {
        dateTime = dateTime.withDayOfMonth(day);
    }

    public int getHour() {
        return dateTime.getHour();
    }

    public void setHour(int hour) {
        dateTime = dateTime.withHour(hour);
    }

    public int getMinute() {
        return dateTime.getMinute();
    }


    public void setMinute(int minute) {
        dateTime = dateTime.withMinute(minute);
    }

    public int getSecond() {
        return dateTime.getSecond();
    }

    public void setSecond(int second) {
        dateTime = dateTime.withSecond(second);
    }

    protected abstract LocalDateTime toLocalDateTime(T from);

    protected abstract T fromLocalDateTime(LocalDateTime from);

    public synchronized void addChangeListener(ChangeListener changeListener) {
        changeListeners.add(changeListener);
    }

    public synchronized void removeChangeListener(ChangeListener changeListener) {
        changeListeners.remove(changeListener);
    }

}